﻿// ReSharper disable FunctionNeverReturns
// ReSharper disable UnreachableCode
// ReSharper disable ConditionIsAlwaysTrueOrFalse
#pragma warning disable 162
namespace Eldert.BTUG.IoT.Device.RaspberryPi2
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading.Tasks;

    using Data.Engine;

    /// <summary>
    /// Class used to process engine readings.
    /// </summary>
    internal class ProcessEngineReadings
    {
        /// <summary>
        /// Boolean indicating if we want to simulate a single or multiple ships.
        /// </summary>
        private const bool SIMULATE_MULTIPLE_SHIPS = false;

        /// <summary>
        /// Send engine readings to IoT Hub.
        /// </summary>
        internal static async void Send()
        {
            // Get sample engines
            var engines = Engine.GetSampleEngines();

            // Run continuously
            while (true)
            {
                // Loop through all ships
                foreach (var ship in GetShips())
                {
                    // Loop through all engines
                    foreach (var engine in engines)
                    {
                        // Set values for when engine is not running
                        var temperature = 0;
                        var oilPressure = 0;
                        var fuelConsumption = 0;
                        var rpm = 0;
                        var clockValue = engine.CurrentClockValue;
                        var tempAlarm = false;
                        var pressureAlarm = false;
                        var filterChangeComing = engine.FilterChangeUpcoming;
                        var currentTime = DateTime.Now;

                        // Check if engine is running
                        if (engine.IsRunning)
                        {
                            // Set values for when engine is running
                            // For demo purposes, we will make temperature leading for other values
                            temperature = new Random().Next(engine.OperatingTemperaturesBetween[0], engine.OperatingTemperaturesBetween[1]);
                            oilPressure = temperature * new Random().Next(28, 32);
                            fuelConsumption = temperature / new Random().Next(9, 11);
                            rpm = temperature * new Random().Next(9, 11);
                            clockValue = engine.CurrentClockValue++;
                            tempAlarm = temperature > engine.WarningTemperature;
                            pressureAlarm = oilPressure > engine.WarningTemperature * 28;
                        }
                        
                        // Send new EngineReadings object to the IoT Hub
                        await IoTHubProxy.Send(
                                new EngineReadings
                                    {
                                        Ship = ship,
                                        Engine = engine.Name,
                                        Temperature = temperature,
                                        FuelConsumption = fuelConsumption,
                                        OilPressure = oilPressure,
                                        RPM = rpm,
                                        TemperatureAlarmActivated = tempAlarm,
                                        OilPressureAlarmActivated = pressureAlarm,
                                        ClockValue = clockValue,
                                        FilterChangeComing = filterChangeComing,
                                        Time = currentTime
                                    });

                        // Debug info
                        Debug.WriteLine($"--- {currentTime} --- Ship: {ship} Engine: {engine.Name} Temperature: {temperature} Clock: {clockValue}");

                        // Do not constantly warn for upcoming filter changes
                        if (filterChangeComing)
                        {
                            engine.HoursBetweenFilterChanges += 500;
                        }
                    }
                }

                // Wait
                await Task.Delay(Convert.ToInt32(SettingsManagement.GetSetting("SecondsBetweenSends")) * 1000);
            }
        }

        /// <summary>
        /// Get names of the ships.
        /// </summary>
        /// <returns>Names of the ships.</returns>
        private static IEnumerable<string> GetShips()
        {
            return SIMULATE_MULTIPLE_SHIPS ? new[] { "Hydra", "Hydra 2", "Kotank", "Kotank II", "Kontank III", "Somtrans XXXI", "Somtrans X" } : new[] { SettingsManagement.GetSetting("ShipName") };
        }
    }
}